package com.xbongbong.paas.help.menu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.dao.PaasPrintTemplateDao;
import com.xbongbong.paas.domain.entity.BusinessRuleInfoEntity;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.PaasPrintTemplateEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.BIProductReformEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.enums.MenuTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.LowCodeHelp;
import com.xbongbong.paas.model.BusinessRuleInfoModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.AccordConfigMenuPojo;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.pojo.dto.FormEntityUpdateDTO;
import com.xbongbong.paas.pojo.dto.FormExplainAddDTO;
import com.xbongbong.paas.pojo.dto.MenuFormAddDTO;
import com.xbongbong.paas.pojo.dto.MenuGroupAddDTO;
import com.xbongbong.paas.service.CompanyConfigService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.service.PackageService;
import com.xbongbong.paas.service.init.AbstractInitMenuHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.AccordConfigMenuEnum;
import com.xbongbong.pro.enums.menu.enums.JXCMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.form.pojo.dto.FormAddBatchDTO;
import com.xbongbong.pro.form.pojo.dto.FormUpdateBatchDTO;
import com.xbongbong.pro.form.pojo.vo.FormAddBatchVO;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainAddBatchDTO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainAddBatchVO;
import com.xbongbong.pro.fundset.pojo.FundSetTransitionPojo;
import com.xbongbong.pro.menu.pojo.dto.MenuFormAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuGroupAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuGroupAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuInitVO;
import com.xbongbong.pro.packageInfo.pojo.vo.BasePackageInfoVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.PrintTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.factory.business.AccordConfigAddMendFactory;
import com.xbongbong.saas.help.LabelHelp;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.AccordConfigAddMenuHandle;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/1/28 15:14
 * @since v1.0
 */
@Component
public class InitJxcMenuHelp extends AbstractInitMenuHelp {

    private static final Logger LOG = LoggerFactory.getLogger(InitJxcMenuHelp.class);

    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasPrintTemplateDao paasPrintTemplateDao;
    @Resource
    private BusinessRuleInfoModel businessRuleInfoModel;
    @Resource
    private CompanyConfigService companyConfigService;
    @Resource
    private LabelHelp labelHelp;
    @Resource
    private LowCodeHelp lowCodeHelp;
    @Resource
    private PackageService packageService;
    @Resource
    private InitFundManagementMenuHelp initFundManagementMenuHelp;

    @Override
    public List<String> alias() {
        return Arrays.asList(SystemAppMenuEnum.JXC.getAlias());
    }
    @Override
    public MenuInitVO initApp(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        PaasFormEntityExt paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(),menuInitDTO.getCorpid());
        if (Objects.isNull(paasFormEntity)) {
            paasFormEntity = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.PRODUCT.getCode(),menuInitDTO.getCorpid());
        }
        menuInitDTO.setProductForm(paasFormEntity);
        MenuInitVO jxcMenuInitVO = initMenu(menuInitDTO, appMap);
        if(Objects.isNull(jxcMenuInitVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        MenuInitVO fundMenuInitVO = initFundManagementMenuHelp.initMenu(menuInitDTO, appMap);
        //插入资金管理默认打印模板
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),fundMenuInitVO.getFormList(),XbbRefTypeEnum.PAY_MANAGEMENT.getAlias(), DistributorMarkEnum.OTHER.getCode());
        afterUpdateFundManagementMenu(menuInitDTO, appMap);
        // 插入JXC默认打印模板
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),jxcMenuInitVO.getFormList(),menuInitDTO.getAlias(), DistributorMarkEnum.OTHER.getCode());
        // 若使用镜像，开启进销存时产品若没有开启要同步开启
        setProductByMirror(menuInitDTO.getCorpid());
        return jxcMenuInitVO;
    }

    /**
     * jxc菜单初始化
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @return void
     * @throws XbbException
     */
    @Override
    public MenuInitVO initMenu(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            // 获取下应用id
            menuInitDTO.setAppId(appMap.get(SystemAppMenuEnum.JXC.getAlias()).getId());
            // 插入菜单分组
            MenuGroupAddBatchVO menuGroupAddBatchVO = groupAddBatch(menuInitDTO);
            if(Objects.isNull(menuGroupAddBatchVO)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入除分组外对应的菜单
            MenuFormAddBatchVO menuFormAddBatchVO = formAddBatch(menuInitDTO, menuGroupAddBatchVO);
            if (Objects.isNull(menuFormAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<PaasMenuEntity> menuGroupList = menuGroupAddBatchVO.getMenuList();
            List<PaasMenuEntity> menuFormList = menuFormAddBatchVO.getMenuList();
            List<PaasMenuEntity> menuList = new ArrayList<>();
            menuList.addAll(menuGroupList);
            menuList.addAll(menuFormList);
            // 插入菜单对应的表单
            FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
            List<FormEntityAddDTO> formList = new ArrayList<>();
            // 通过分组菜单，得到需要插入的表单列表
            getFormList(formList, menuList);
            formAddBatchDTO.setFormList(formList);
            FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
            if (Objects.isNull(formAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入表单对应的字段解释
            formExplainAddBatch(menuInitDTO, formAddBatchVO);
            menuInitVO.setFormList(formAddBatchVO.getFormList());
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitJxcMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    /**
     * 回退进销存表单到初始化
     * @param mirrorRollBackDTO
     * @param systemFormList 安装的系统表单
     * @param paasProductFormEntity
     * @throws XbbException
     * @author guohui.zhang
     */
    @Override
    public void rollBackInit(MirrorRollBackDTO mirrorRollBackDTO, List<Long> systemFormList, PaasFormEntity paasProductFormEntity) throws XbbException {
        String targetCorpid = mirrorRollBackDTO.getTargetCorpid();
        Long appId = mirrorRollBackDTO.getAppId();
        try {
            // 1. 回退菜单(根据安装的系统表单反推菜单)
            HashSet<Long> menuIds = new HashSet<>();
            HashMap<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("idIn", systemFormList);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormEntity> sysInstallFormList = paasFormModel.findEntity(param);
            sysInstallFormList.forEach(item -> {
                menuIds.add(item.getMenuId());
            });
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("idIn", menuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasMenuEntity> paasMenuList = paasMenuModel.findEntitys(param);
            // 补充: 根据子菜单查父菜单
            HashSet<Long> parentMenuIds = new HashSet<>();
            paasMenuList.forEach(item -> {
                parentMenuIds.add(item.getParentId());
            });
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("parentId", 0L);
            param.put("idIn", parentMenuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasMenuEntity> parentMenuList = paasMenuModel.findEntitys(param);
            paasMenuList.addAll(parentMenuList);
            updateInitMenu(paasMenuList, targetCorpid);

            // 2. 回退表单(根据菜单找所有表单)
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("menuIdIn", menuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormEntity> paasFormList = paasFormModel.findEntity(param);
            List<FormEntityUpdateDTO> formList = new ArrayList<>();
            HashSet<Long> formIds = new HashSet<>();
            paasFormList.forEach(item -> {
                FormEntityUpdateDTO formEntityUpdateDTO = new FormEntityUpdateDTO();
                BeanUtil.copyProperties(item, formEntityUpdateDTO);
                formList.add(formEntityUpdateDTO);
                formIds.add(item.getId());
            });
            getUpdateFormList(formList);
            FormUpdateBatchDTO formUpdateBatchDTO = new FormUpdateBatchDTO();
            formUpdateBatchDTO.setCorpid(targetCorpid);
            formUpdateBatchDTO.setFormList(formList);
            paasFormService.updateBatch4Mirror(formUpdateBatchDTO);

            // 3. 表单解释
            param.clear();
            param.put("corpid", mirrorRollBackDTO.getTargetCorpid());
            param.put("appId", mirrorRollBackDTO.getAppId());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("formIdIn", formIds);
            param.put("saasMark", SaasMarkEnum.SAAS.getCode());
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
            formExplainUpdateBatch(paasProductFormEntity, paasFormExplainEntityList, mirrorRollBackDTO.getTargetCorpid());

            // 更新应用信息(待定)
            /*PaasAppEntity paasAppEntity = paasAppModel.getByKey(mirrorRollBackDTO.getAppId(), mirrorRollBackDTO.getTargetCorpid());
            SystemAppMenuEnum systemAppMenuEnum = SystemAppMenuEnum.getSystemAppMenuEnum(mirrorRollBackDTO.getAlias());
            AccessLinkEnum accessLinkEnum = systemAppMenuEnum.getAccessLinkEnum();
            paasAppEntity.setIcon(accessLinkEnum.getIcon());
            paasAppEntity.setColor(accessLinkEnum.getColor());
            paasAppEntity.setName(systemAppMenuEnum.getName());
            paasAppModel.update(paasAppEntity);*/

            //更新打印模板
            rollBackToDefaultPrintTemplates(targetCorpid,appId,paasFormList,mirrorRollBackDTO.getAlias(),formIds);

            // 初始化时是没有业务规则的，所以删除表单对应的所有业务规则
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("formIdIn", formIds);
            param.put("saasMark", SaasMarkEnum.SAAS.getCode());
            List<BusinessRuleInfoEntity> ruleInfoEntityList = businessRuleInfoModel.findEntitys(param);
            Set<Long> ruleIdSets = new HashSet<>();
            ruleInfoEntityList.forEach(item -> ruleIdSets.add(item.getId()));
            List<Long> ruleIdIn = new ArrayList<>(ruleIdSets);
            if (ruleIdIn.size() > 0) {
                businessRuleInfoModel.deleteBatch(ruleIdIn, targetCorpid);
            }
            // 标签初始化
            labelHelp.deleteAllAndinit(paasFormList, targetCorpid, appId);

            // 初始化时没有低代码，此处删除所有低代码及配置
            lowCodeHelp.deleteLowCode(targetCorpid, formIds);

        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }
    private void updateInitMenu(List<PaasMenuEntity> paasMenuEntites, String corpid) throws XbbException {
        try {
            for (PaasMenuEntity paasMenuEntite : paasMenuEntites) {
                JXCMenuEnum menuEnum = JXCMenuEnum.getByAlias(paasMenuEntite.getAlias());
                paasMenuEntite.setName(menuEnum.getName());
                AccessLinkEnum accessLinkEnum = menuEnum.getAccessLinkEnum();
                paasMenuEntite.setIcon(accessLinkEnum.getIcon());
                paasMenuEntite.setEnable(EnableEnum.OPEN.getCode());
                paasMenuEntite.setColor(accessLinkEnum.getColor());
                paasMenuEntite.setUrl(accessLinkEnum.getUrl());
                paasMenuEntite.setType(menuEnum.getType());
                paasMenuEntite.setMobileUrl(accessLinkEnum.getMobileUrl());
            }
            paasMenuModel.updateBatch(paasMenuEntites,corpid);
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainAddBatch批量修改菜单信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    public List<PaasFormExplainEntity> formExplainUpdateBatch( PaasFormEntity paasProductFormEntity, List<PaasFormExplainEntity> paasFormExplainEntityList,String corpid) throws XbbException {
        try {
            FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(corpid);
            for (PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList) {
                String alias = XbbRefTypeEnum.getByCode(paasFormExplainEntity.getBusinessType()).getAlias();
                paasFormExplainEntity.setExplains(JSON.toJSONString(InitExplainsHelper.initFieldAttrEntity(alias, paasProductFormEntity, fundSetTransitionPojo, 0)));
            }
            paasFormExplainModel.updateBatch(paasFormExplainEntityList,corpid);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainAddBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormExplainEntityList;
    }

    /**
     * 更新表单到初始化
     * @param formList
     * @return
     * @throws XbbException
     */
    private List<FormEntityUpdateDTO> getUpdateFormList(List<FormEntityUpdateDTO> formList) throws XbbException{
        try {
            for (FormEntityUpdateDTO formEntityAddDTO : formList) {
                if (Objects.equals(formEntityAddDTO.getDel(),DelEnum.NORMAL.getDel())) {
                    JXCMenuEnum menuEnum = JXCMenuEnum.getByCode(formEntityAddDTO.getBusinessType());
                    if (Objects.nonNull(menuEnum)){
                        formEntityAddDTO.setName(menuEnum.getName());
                        formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                        formEntityAddDTO.setCustomTitle(getAppDefaultTitle(menuEnum.getCode()));
                        formEntityAddDTO.setLabels(getAppDefaultLabel(menuEnum.getCode()));
                        formEntityAddDTO.setSummary(getAppDefaultSummary(menuEnum.getCode()));
                        formEntityAddDTO.setBusinessRules("0");
                        formEntityAddDTO.setAssociationList(new ArrayList<>());
                    }else if (Objects.equals(formEntityAddDTO.getBusinessType(),XbbRefTypeEnum.WAREHOUSE_PRODUCT.getCode())){
                        formEntityAddDTO.setName(XbbRefTypeEnum.STOCK_PRODUCT.getName());
                        formEntityAddDTO.setBusinessRules("0");
                        formEntityAddDTO.setAssociationList(new ArrayList<>());
                    }else if (Objects.equals(formEntityAddDTO.getBusinessType(),XbbRefTypeEnum.STOCK_PRODUCT.getCode())){
                        //库存产品不做处理
                    }else {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                    }
                }
            }
        }catch (XbbException e) {
            throw e;
        }
        return formList;
    }


    /**
     * 添加表单字段解释
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @param formAddBatchVO 表单数据
     * @return 返回表单字段对象
     * @throws XbbException
     */
    public FormExplainAddBatchVO formExplainAddBatch(MenuInitDTO menuInitDTO, FormAddBatchVO formAddBatchVO) throws XbbException {
        FormExplainAddBatchVO formExplainAddBatchVO;
        try {
            List<PaasFormEntity> formResultList = formAddBatchVO.getFormList();
            FormExplainAddBatchDTO formExplainAddBatchDTO = new FormExplainAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formExplainAddBatchDTO);
            List<FormExplainAddDTO> formExplainList = new ArrayList<>();
            FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(menuInitDTO.getCorpid());
            for (PaasFormEntity item : formResultList) {
                // 过滤掉bi的一些表单
                BIProductReformEnum biProductReformEnum = BIProductReformEnum.getEnumByProductBusinessType(item.getBusinessType());
                if (Objects.nonNull(biProductReformEnum) ||
                        Objects.equals(item.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                    continue;
                }
                FormExplainAddDTO formExplainAddDTO = new FormExplainAddDTO();
                BeanUtil.copyProperties(item, formExplainAddDTO);
                formExplainAddDTO.setFormId(item.getId());
                String alias = XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias();
                // 初始化方法获取字段列表
                List<FieldAttrEntity> explainList = new ArrayList<>();
                if (!InitExplainsHelper.EMPTY_EXPLAIN.contains(item.getBusinessType())) {
                   explainList = InitExplainsHelper.initFieldAttrEntity(alias, menuInitDTO.getProductForm(), fundSetTransitionPojo, 0);
                }
                formExplainAddDTO.setFormList(explainList);
                formExplainList.add(formExplainAddDTO);
            }
            formExplainAddBatchDTO.setFormExplainList(formExplainList);
            formExplainAddBatchVO = paasFormExplainService.addBatch(formExplainAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitJxcMenuHelp.formExplainAddBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainAddBatchVO;
    }

    /**
     * 根据菜单获取表单列表
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param formList 表单列表
     * @param menuList 菜单列表
     * @return 返回需要插入的表单列表
     * @throws XbbException 业务异常
     */
    public List<FormEntityAddDTO> getFormList(List<FormEntityAddDTO> formList, List<PaasMenuEntity> menuList) throws XbbException {
        try {
            for (PaasMenuEntity item : menuList) {
                FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
                BeanUtil.copyProperties(item, formEntityAddDTO);
                JXCMenuEnum jxcMenuEnum = JXCMenuEnum.getByAlias(item.getAlias());
                if (Objects.isNull(jxcMenuEnum)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                }
                // 进销存用表单的alias获取业务
                if(MenuTypeEnum.GROUP.getType().equals(jxcMenuEnum.getType()) || MenuTypeEnum.MENU.getType().equals(jxcMenuEnum.getType())) {
                    continue;
                }
                formEntityAddDTO.setBusinessType(jxcMenuEnum.getCode());
                formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                formEntityAddDTO.setLabels(getAppDefaultLabel(jxcMenuEnum.getCode()));
                formEntityAddDTO.setCustomTitle(getAppDefaultTitle(jxcMenuEnum.getCode()));
                formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(jxcMenuEnum.getCode()));
                formEntityAddDTO.setMenuId(item.getId());
                formList.add(formEntityAddDTO);
                // 库存产品
                if (XbbRefTypeEnum.WAREHOUSE.getAlias().equals(item.getAlias())) {
                    formList.add(getStockProduct(item));
                }
            }
        }catch (XbbException e) {
            throw e;
        }
        return formList;
    }

    /**
     * 根据菜单获取表单列表
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param formList 表单列表
     * @param menuList 菜单列表
     * @return 返回需要插入的表单列表
     * @throws XbbException 业务异常
     */
    public List<FormEntityAddDTO> getAccordConfigFormList(List<FormEntityAddDTO> formList, List<PaasMenuEntity> menuList, AccordConfigMenuEnum accordConfigMenuEnum) {
        for (PaasMenuEntity item : menuList) {
            FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
            BeanUtil.copyProperties(item, formEntityAddDTO);
            formEntityAddDTO.setEnable(1);
            formEntityAddDTO.setBusinessType(accordConfigMenuEnum.getCode());
            formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formEntityAddDTO.setLabels(getAppDefaultLabel(accordConfigMenuEnum.getCode()));
            formEntityAddDTO.setCustomTitle(getAppDefaultTitle(accordConfigMenuEnum.getCode()));
            formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(accordConfigMenuEnum.getCode()));
            formEntityAddDTO.setMenuId(item.getId());
            formList.add(formEntityAddDTO);
        }
        return formList;
    }
    /**
     * 新建批次流水表单
     * @author feng.zheng
     * @date 2020/5/28 18:44
     * @param item 流水查询菜单
     * @param formList 需要插入的表单
     * @return 含有批次流水的表单列表
     */
    public List<FormEntityAddDTO> getBatchFlowBill(PaasMenuEntity item, List<FormEntityAddDTO> formList){
        FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
        BeanUtil.copyProperties(item, formEntityAddDTO);
        formEntityAddDTO.setName(I18nMessageUtil.getMessage(BusinessConstant.BATCH_FLOW_BILL_NAME));
        formEntityAddDTO.setBusinessType(XbbRefTypeEnum.BATCH_FLOW_BILL.getCode());
        formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formEntityAddDTO.setLabels(getAppDefaultLabel(XbbRefTypeEnum.BATCH_FLOW_BILL.getCode()));
        formEntityAddDTO.setCustomTitle(getAppDefaultTitle(XbbRefTypeEnum.BATCH_FLOW_BILL.getCode()));
        formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(XbbRefTypeEnum.BATCH_FLOW_BILL.getCode()));
        formEntityAddDTO.setMenuId(item.getId());
        formEntityAddDTO.setEnable(1);
        formList.add(formEntityAddDTO);
        return formList;
    }

    /**
     * 库存产品
     * @param paasMenuEntity
     * @return
     */
    private FormEntityAddDTO getStockProduct(PaasMenuEntity paasMenuEntity) {
        FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
        BeanUtil.copyProperties(paasMenuEntity, formEntityAddDTO);
        formEntityAddDTO.setBusinessType(XbbRefTypeEnum.STOCK_PRODUCT.getCode());
        formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formEntityAddDTO.setBusinessRules("0");
        formEntityAddDTO.setName(XbbRefTypeEnum.STOCK_PRODUCT.getName());
        formEntityAddDTO.setMenuId(paasMenuEntity.getId());
        return formEntityAddDTO;
    }

    /**
     * 批量添加表单
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param menuInitDTO
     * @param menuGroupAddBatchVO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO
     * @throws XbbException
     */
    private MenuFormAddBatchVO formAddBatch(MenuInitDTO menuInitDTO, MenuGroupAddBatchVO menuGroupAddBatchVO) throws XbbException {
        MenuFormAddBatchVO menuFormAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            //获取公司配置
            BasePackageInfoVO basePackageInfoVO = packageService.getBasePackageInfoFromRedis(menuInitDTO.getCorpid());
            Map<String, PaasMenuEntity> menuMap = new HashMap<>(menuGroupAddBatchVO.getMenuList().size());
            menuGroupAddBatchVO.getMenuList().forEach((item)->{
                menuMap.put(item.getAlias(), item);
            });
            MenuFormAddBatchDTO menuFormAddBatchDTO = new MenuFormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, menuFormAddBatchDTO);
            menuFormAddBatchDTO.setAppId(appId);
            List<MenuFormAddDTO> menuFormMenuList = new ArrayList<>();
            for(JXCMenuEnum menuEnum: JXCMenuEnum.values()){
                if(StringUtil.isEmpty(menuEnum.getParent())){
                    // 踢掉分组
                    continue;
                }
                // 成本改造 所有公司都有库存流水 且不允许关闭了
//                if(Objects.equals(menuEnum, JXCMenuEnum.STOCK_FLOW_BILL) || Objects.equals(menuEnum, JXCMenuEnum.STOCK_STANDING_BOOK)){
//                    // 先注释掉新公司初始化
//                    continue;
//                }
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setAppId(appId);
                if(StringUtil.isEmpty(menuEnum.getParent())){
                    menuFormAddDTO.setParentId(0L);
                }else{
                    menuFormAddDTO.setParentId(menuMap.get(menuEnum.getParent()).getId());
                }
                menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                menuFormAddDTO.setAlias(menuEnum.getAlias());
                menuFormAddDTO.setName(menuEnum.getName());
                AccessLinkEnum accessLinkEnum = menuEnum.getAccessLinkEnum();
                menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
                menuFormAddDTO.setColor(accessLinkEnum.getColor());
                menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
                menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                menuFormAddDTO.setType(menuEnum.getType());
                menuFormMenuList.add(menuFormAddDTO);
            }
            menuFormAddBatchDTO.setMenuList(menuFormMenuList);
            menuFormAddBatchVO = paasMenuService.addBatchFormMenu(menuFormAddBatchDTO);
            // 将crm的产品查询改为库存查询
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitJxcMenuHelp.formAddBatch批量添加表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuFormAddBatchVO;
    }

    /**
     * 批量添加分组
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param menuInitDTO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuGroupAddBatchVO
     * @throws XbbException
     */
    private MenuGroupAddBatchVO groupAddBatch(MenuInitDTO menuInitDTO) throws XbbException{
        MenuGroupAddBatchVO menuGroupAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            MenuGroupAddBatchDTO menuGroupAddBatchDTO = new MenuGroupAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, menuGroupAddBatchDTO);
            menuGroupAddBatchDTO.setAppId(appId);
            List<MenuGroupAddDTO> groupMenuList = new ArrayList<>();
            for(JXCMenuEnum jxcMenuEnum: JXCMenuEnum.values()){
                if(StringUtil.isEmpty(jxcMenuEnum.getParent())){
                    MenuGroupAddDTO jxcMenuGroupAddDTO = new MenuGroupAddDTO();
                    BeanUtil.copyProperties(menuInitDTO, jxcMenuGroupAddDTO);
                    jxcMenuGroupAddDTO.setParentId(0L);
                    jxcMenuGroupAddDTO.setAppId(appId);
                    jxcMenuGroupAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    jxcMenuGroupAddDTO.setAlias(jxcMenuEnum.getAlias());
                    jxcMenuGroupAddDTO.setName(jxcMenuEnum.getName());
                    AccessLinkEnum accessLinkEnum = jxcMenuEnum.getAccessLinkEnum();
                    jxcMenuGroupAddDTO.setIcon(accessLinkEnum.getIcon());
                    jxcMenuGroupAddDTO.setColor(accessLinkEnum.getColor());
                    jxcMenuGroupAddDTO.setUrl(accessLinkEnum.getUrl());
                    jxcMenuGroupAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                    jxcMenuGroupAddDTO.setType(jxcMenuEnum.getType());
                    groupMenuList.add(jxcMenuGroupAddDTO);
                }
            }
            menuGroupAddBatchDTO.setMenuList(groupMenuList);
            menuGroupAddBatchVO = paasMenuService.addBatchGroupMenu(menuGroupAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitJxcMenuHelp.groupAddBatch批量添加分组出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuGroupAddBatchVO;
    }

    /**
     * 初始化，为公司saas模块增加默认打印模板
     * @param  corpid
     * @param  appId
     * @param formList 表单列表
     * @param appAlias 应用alias
     */
    private void rollBackToDefaultPrintTemplates(String corpid,Long appId, List<PaasFormEntity> formList, String appAlias,HashSet<Long> formIds) {
        try {
            List<PrintTemplateTypeEnum> printTemplateTypeList = PrintTemplateTypeEnum.getAllEnums();
            List<Integer> businessTypeList = new ArrayList<>();
            for (PrintTemplateTypeEnum printTemplateTypeEnum : printTemplateTypeList) {
                if (printTemplateTypeEnum.getApp().equals(appAlias)) {
                    businessTypeList.add(printTemplateTypeEnum.getCode());
                }
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("columns", " id , name");
            param.put("corpid", corpid);
            param.put("appId", appId);
            param.put("formIdIn", formIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<Long> delIds = new ArrayList<>();
            List<PaasPrintTemplateEntity> paasPrintTemplateEntityList = paasPrintTemplateDao.findEntitys(param);
            for (PaasPrintTemplateEntity paasPrintTemplateEntity : paasPrintTemplateEntityList) {
                delIds.add(paasPrintTemplateEntity.getId());
            }
            if (delIds.size()>0) {
                paasPrintTemplateDao.deleteBatch(delIds, corpid);
            }
            param.clear();
            param.put("corpid", "0");
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasPrintTemplateEntity> defaultList = paasPrintTemplateDao.findEntitys(param);
            if (defaultList.isEmpty()) {
                // 数据库中没有存在默认模板配置
                return;
            }
            Map<Integer, PaasPrintTemplateEntity> defaultTemplateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasPrintTemplateEntity templateEntity : defaultList) {
                defaultTemplateMap.put(templateEntity.getBusinessType(), templateEntity);
            }
            long now = DateTimeUtil.getInt();
            List<PaasPrintTemplateEntity> insertList = new ArrayList<>();
            for (PaasFormEntity paasFormEntity : formList) {
                Integer businessType = paasFormEntity.getBusinessType();
                if (!businessTypeList.contains(businessType)) {
                    // 无打印的业务跳过；
                    continue;
                }
                PaasPrintTemplateEntity defaultEntity = defaultTemplateMap.get(businessType);
                if (defaultEntity == null) {
                    continue;
                }
                PaasPrintTemplateEntity paasPrintTemplateEntity = new PaasPrintTemplateEntity();
                paasPrintTemplateEntity.setName("默认模板");
                paasPrintTemplateEntity.setCorpid(corpid);
                paasPrintTemplateEntity.setAppId(paasFormEntity.getAppId());
                paasPrintTemplateEntity.setMenuId(paasFormEntity.getMenuId());
                paasPrintTemplateEntity.setFormId(paasFormEntity.getId());
                paasPrintTemplateEntity.setCreatorId("0");
                paasPrintTemplateEntity.setEnable(BasicConstant.ONE);
                paasPrintTemplateEntity.setAddTime(now);
                paasPrintTemplateEntity.setUpdateTime(now);
                paasPrintTemplateEntity.setBusinessType(businessType);
                paasPrintTemplateEntity.setHtml(defaultEntity.getHtml());
                paasPrintTemplateEntity.setConfigInfo(defaultEntity.getConfigInfo());
                insertList.add(paasPrintTemplateEntity);
            }

            if (insertList.size()>0) {
                paasPrintTemplateDao.insertBatch(insertList);
            }
        } catch (Exception e) {
            LOG.error("初始化" + appAlias + "打印模板失败：", e);
            throw e;
        }
    }

    public void addAccordConfigMenu(AccordConfigMenuPojo accordConfigMenuPojo) throws XbbException {
        CompanyConfigEntity configEntity = accordConfigMenuPojo.getConfigEntity();
        if (Objects.isNull(configEntity)) {
            AccordConfigAddMendFactory.getByConfigEnum(accordConfigMenuPojo.getConfigEnum()).addMenu(accordConfigMenuPojo);
        } else {
            AccordConfigMenuEnum accordConfigMenuEnum = AccordConfigMenuEnum.getByCompanyConfig(accordConfigMenuPojo.getConfigEnum());
            if (Objects.isNull(accordConfigMenuEnum)) {
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
            }
            PaasMenuEntity paasMenuEntity = paasMenuModel.getByAlias(accordConfigMenuEnum.getAlias(), accordConfigMenuPojo.getCorpid());
            if (Objects.isNull(paasMenuEntity)) {
                AccordConfigAddMenuHandle accordConfigAddMenuHandle = AccordConfigAddMendFactory.getByConfigEnum(accordConfigMenuPojo.getConfigEnum());
                accordConfigAddMenuHandle.addMenu(accordConfigMenuPojo);
            } else {
                boolean isUse = BasicConstant.IS_USE.toString().equals(accordConfigMenuPojo.getConfigValue());
                paasMenuEntity.setEnable(isUse? 1 : 0);
                paasMenuModel.update(paasMenuEntity);
                if (Objects.equals(accordConfigMenuEnum, AccordConfigMenuEnum.STOCK_FLOW_BILL)) {
                    PaasMenuEntity standingBookMenuEntity = paasMenuModel.getByAlias(XbbRefTypeEnum.STOCK_STANDING_BOOK.getAlias(), accordConfigMenuPojo.getCorpid());
                    if (Objects.nonNull(standingBookMenuEntity)) {
                        standingBookMenuEntity.setEnable(isUse? 1 : 0);
                        paasMenuModel.update(standingBookMenuEntity);
                    }
                    PaasMenuEntity batchFlowMenuEntity = paasMenuModel.getByAlias(XbbRefTypeEnum.BATCH_FLOW_BILL.getAlias(), accordConfigMenuPojo.getCorpid());
                    if (Objects.nonNull(batchFlowMenuEntity)) {
                        String value = companyConfigService.getCompanyConfigSetValue(accordConfigMenuPojo.getCorpid(), CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias());
                        if (Objects.equals(BasicConstant.IS_USE.toString(), value) && isUse) {
                            batchFlowMenuEntity.setEnable(1);
                        } else {
                            batchFlowMenuEntity.setEnable(0);
                        }
                        paasMenuModel.update(batchFlowMenuEntity);
                    }
                }
            }
        }
    }

    /**
     * 根据菜单生成表单和表单解释
     *
     * @param accordConfigMenuPojo
     * @param corpid
     * @param now
     * @param seqMenuEntity
     * @param accordConfigMenuEnum
     * @throws XbbException
     */
    public void generateFormWithMenu(AccordConfigMenuPojo accordConfigMenuPojo, String corpid, long now, PaasMenuEntity seqMenuEntity, AccordConfigMenuEnum accordConfigMenuEnum) throws XbbException {
        PaasFormEntity seqFormEntity = new PaasFormEntity();
        FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
        BeanUtil.copyProperties(formEntityAddDTO, seqFormEntity);
        BeanUtil.copyProperties(seqMenuEntity, seqFormEntity);
        seqFormEntity.setCoOpPerms(JSONObject.toJSONString(formEntityAddDTO.getCoOpPerms()));
        seqFormEntity.setSurcharge(JSONObject.toJSONString(formEntityAddDTO.getSurcharge()));
        seqFormEntity.setBusinessType(accordConfigMenuEnum.getCode());
        seqFormEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
        seqFormEntity.setLabels(JSON.toJSONString(getAppDefaultLabel(accordConfigMenuEnum.getCode())));
        seqFormEntity.setCustomTitle(JSON.toJSONString(getAppDefaultTitle(accordConfigMenuEnum.getCode())));
        seqFormEntity.setSummary(JSON.toJSONString(getAppDefaultSummary(accordConfigMenuEnum.getCode())));
        seqFormEntity.setMenuId(seqMenuEntity.getId());
        seqFormEntity.setAddTime(now);
        seqFormEntity.setUpdateTime(now);
        seqFormEntity.setCreatorId(accordConfigMenuPojo.getUserId());
        seqFormEntity.setAssociationList(JSONObject.toJSONString(formEntityAddDTO.getAssociationList()));
        seqFormEntity.setBusinessRules(JSONObject.toJSONString(formEntityAddDTO.getBusinessRules()));
        seqFormEntity.setEnable(1);
        //增加隐藏标志默认值
        seqFormEntity.setHidden(BasicConstant.ZERO);
        paasFormModel.insert(seqFormEntity);
        PaasFormEntity productForm = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
        PaasFormExplainEntity seqExplainEntity = new PaasFormExplainEntity();
        BeanUtil.copyProperties(seqFormEntity, seqExplainEntity);
        seqExplainEntity.setFormId(seqFormEntity.getId());
        seqExplainEntity.setEnable(1);
        // 初始化方法获取字段列表
        List<FieldAttrEntity> explainList = new ArrayList<>();
        if (!InitExplainsHelper.EMPTY_EXPLAIN.contains(accordConfigMenuEnum.getType())) {
            FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(corpid);
            explainList = InitExplainsHelper.initFieldAttrEntity(accordConfigMenuEnum.getAlias(), productForm, fundSetTransitionPojo, 0);
        }
        seqExplainEntity.setExplains(JSON.toJSONString(explainList));
        seqExplainEntity.setAddTime(now);
        seqExplainEntity.setUpdateTime(now);
        paasFormExplainModel.insert(seqExplainEntity);
    }

}
